#pragma once

#include <uv.h>
#include <atomic>
#include <functional>
#include <memory>
#include <cstdlib>
#include <mutex>
#include <cassert>
#include <thread>
#include <list>
#include <vector>
#include <algorithm>
#include <condition_variable>
#include <map>
#include <cstring>

#if (defined PLATFORM_APPLE) || (defined PLATFORM_LINUX)

#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>

#define INVALID_SOCKET (-1)

#endif

#ifdef PLATFORM_APPLE
#define OPT_NO_SIG_PIPE SO_NOSIGPIPE
#else
#define OPT_NO_SIG_PIPE MSG_NOSIGNAL
#endif

#define SHARED_TYPE(tp) \
        typedef  std::shared_ptr<tp> shared_##tp

#define UNIQUE_TYPE(tp) \
        typedef  std::unique_ptr<tp> unique_##tp

//this marco means that function must be called in event_loop!
#define EV_LOOP_CALL

#define EQ_OR_RETURN(var, x)\
            if((var) != (x))\
            {\
                return;\
            }

#define DISABLE_COPY(Clazz)\
    public : Clazz(const Clazz &) = delete;\
    public : Clazz& operator = (const Clazz &) = delete;

#define DISABLE_MOVE(Clazz)\
    public : Clazz(Clazz &&)  noexcept = delete;\
    public : Clazz& operator = (Clazz &&)  noexcept = delete;

#define DISABLE_COPY_MOVE(Clazz)\
    DISABLE_COPY(Clazz) \
    DISABLE_MOVE(Clazz)

namespace hacks {
    typedef uv_os_sock_t ev_os_sock_t;
    typedef uv_os_fd_t ev_os_fd_t;

    typedef enum {
        evt_init = 0x00,
        evt_commited,
        evt_stopping,
        evt_stopped
    } ev_evt_state;

    template<typename Tp>
    struct ev_buddy {
        std::shared_ptr<Tp> shd_ins;
    };
}
